#include <iostream>

using namespace std;
const int N = 55;
int a[N][N];
int m, n;
int s[2 * N][N][N]; // 使用这个表示状态变化矩阵

int main()
{
    // zdl:: 这道题目和放个取数是一样的同时需要两个七点，应为这两个路径会相互影响
    cin >> m >> n;
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
            cin >> a[i][j];

    for (int k = 2; k <= n + m; k++)
    {
        for (int i1 = 1; i1 <= m; i1++)
        {
            for (int i2 = 1; i2 <= m; i2++)
            {
                int j1 = k - i1, j2 = k - i2;
                if (i1 == i2 && k != n + m)
                    continue;
                // zdl:: 判断越界
                if (j1 < 1 || j1 > n || j2 < 1 || j2 > n)
                    continue;
                // zdl:: 接下来直接更新数值
                int &t = s[k][i1][i2];
                t = max(t, s[k - 1][i1][i2]);
                t = max(t, s[k - 1][i1 - 1][i2 - 1]);
                t = max(t, s[k - 1][i1][i2 - 1]);
                t = max(t, s[k - 1][i1 - 1][i2]);

                t += a[i1][j1] + a[i2][j2];
            }
        }
    }
    // 要搞清楚状态的表示，为什么回事两个 m 应为状态表示方程的两个位置就是便是横坐标的
    cout << s[n + m][m][m];
    return 0;
}